<template>
  <div class="main">
    <!-- 左侧面板条 -->
    <div v-show="leftActivePanels.length>0" class="left-panel-group-container">
      <panel-bar
        :key="panelGroupKey1"
        mode="vertical"
        :panels="leftActivePanels"
        :background="panelBarItemBgStyle"
        :on-panel-state-init="onPanelStateInit"
        :on-panel-state-will-change="onPanelStateWillChange"
      />
    </div>
    <div class="layouts-container">
      <div class="layouts">
        <div
          v-show="layout.left.nActives > 0"
          :class="layout.left.className"
          :style="layout.left.style"
        >
          <!-- iframe会吞掉mouse事件,修复方法:pointer-events: none -->
          <!-- <iframe
      frameborder="0"
      scrolling="no"
      style="pointer-events: none; left: 0px; top: 0px; width: 100%; height: 100%; position: absolute; z-index: -1; background-color: transparent;"
      allowtransparency="true"
          />-->
          <!-- 可调大小的面板 -->
          <v-resizable
            :relative="true"
            :width="resizeParams.left.width"
            :height="resizeParams.left.height"
            :min-width="resizeParams.left.minWidth"
            :active="resizeParams.left.active"
            @resize:move="e => onResizeMove('left', e)"
          >
            <!-- 左侧区域 -->
            <panel-layout :tags="leftPanelTags" />
          </v-resizable>
        </div>
        <!-- 中间区域 -->
        <div :class="layout.main.className" :style="layout.main.style">
          <div class="main-layout-container">
            <div :class="layout.top.className" :style="layout.top.style">
              <!-- 上部区域 -->
              <viewer />
            </div>
            <div
              v-show="layout.bottom.nActives > 0"
              :class="layout.bottom.className"
              :style="layout.bottom.style"
            >
              <!-- 下部区域 -->
              <!-- css样式动态修改后,bottom的div跑到页面顶部,鼠标动一下之后就恢复正常 -->
              <!-- 猜测原因: ocx控件干扰或延迟了页面的刷新 -->
              <!-- 解决方法: 增加iframe遮挡 -->
              <iframe
                frameborder="0"
                scrolling="no"
                style="pointer-events: none; left: 0px; top: 0px; width: 100%; height: 100%; position: absolute; z-index: -1; background-color: transparent;"
                allowtransparency="true"
              />
              <!-- 可调大小的面板 -->
              <v-resizable
                :relative="true"
                :width="resizeParams.bottom.width"
                :height="resizeParams.bottom.height"
                :min-height="resizeParams.bottom.minHeight"
                :active="resizeParams.bottom.active"
                @resize:move="e => onResizeMove('bottom', e)"
              >
                <!-- 下部区域 -->
                <panel-layout :tags="bottomPanelTags" />
              </v-resizable>
            </div>
          </div>
        </div>
        <div
          v-show="layout.right.nActives > 0"
          :class="layout.right.className"
          :style="layout.right.style"
        >
          <!-- <iframe
            frameborder="0"
            scrolling="no"
            style="left: 0px; top: 0px; width: 100%; height: 100%; position: absolute; z-index: -1; background-color: transparent;"
            allowtransparency="true"
          />-->
          <!-- 可调大小的面板 -->
          <v-resizable
            :relative="true"
            :width="resizeParams.right.width"
            :height="resizeParams.right.height"
            :min-width="resizeParams.right.minWidth"
            :active="resizeParams.right.active"
            @resize:move="e => onResizeMove('right', e)"
          >
            <!-- 右侧区域 -->
            <panel-layout :tags="rightPanelTags" />
          </v-resizable>
        </div>
      </div>
    </div>
    <!-- 右侧面板条 -->
    <div v-show="rightActivePanels.length>0" class="right-panel-group-container">
      <panel-bar
        :key="panelGroupKey2"
        mode="vertical"
        :panels="rightActivePanels"
        :background="panelBarItemBgStyle"
        :on-panel-state-init="onPanelStateInit"
        :on-panel-state-will-change="onPanelStateWillChange"
      />
    </div>
  </div>
</template>

<script>
import Resizable from '@/components/Resizable'
import PanelBar from '../components/panel-bar'
import Viewer from './viewer'
import PanelLayout from './panel-layout'
import LayoutConfigDialog from '../config/layout'
import PanelConfig from '../config/panel'
import StyleConfig from '../config/style'
import { mapState } from 'vuex'
import { makeUUID } from '@/utils'

export default {
  name: 'EditorMain',
  components: {
    PanelBar,
    PanelLayout,
    Viewer,
    'v-resizable': Resizable
  },
  data() {
    return {
      resizeParams: {
        left: {
          width: 0,
          height: 0,
          minWidth: LayoutConfigDialog.left.style.minWidth,
          active: ['r']
        },
        right: {
          width: 0,
          height: 0,
          minWidth: LayoutConfigDialog.right.style.minWidth,
          active: ['l']
        },
        bottom: {
          width: 0,
          height: 0,
          minHeight: LayoutConfigDialog.bottom.style.minHeight,
          active: ['t']
        }
      },
      panelGroupKey: '',
      layout: {
        left: {
          className: 'left-layout',
          style: { width: 0 },
          nActives: 0,
          last: ''
        },
        main: {
          className: 'main-layout',
          style: { flex: 0 },
          nActives: 0,
          last: ''
        },
        right: {
          className: 'right-layout',
          style: { width: 0 },
          nActives: 0,
          last: ''
        },
        top: {
          className: 'top-layout',
          style: { flex: 0 },
          nActives: 0,
          last: ''
        },
        bottom: {
          className: 'bottom-layout',
          style: { height: 0 },
          nActives: 0,
          last: ''
        }
      },
      panels: {}
    }
  },
  computed: {
    ...mapState('editor/diagram', {
      consoleState: 'consoleState'
    }),
    panelGroupKey1: function() {
      return this.panelGroupKey + '-20191124-1'
    },
    panelGroupKey2: function() {
      return this.panelGroupKey + '-20191124-2'
    },
    leftActivePanels() {
      return this.getPanels('left')

      // const arr1 = this.getPanels('left')
      // const arr2 = this.getPanels('bottom')
      // return [...arr1, ...arr2]
    },
    rightActivePanels() {
      return this.getPanels('right')
    },
    leftPanelTags() {
      return this.getActivePanels('left')
    },
    rightPanelTags() {
      return this.getActivePanels('right')
    },
    bottomPanelTags() {
      return this.getActivePanels('bottom')
    },
    panelBarItemBgStyle() {
      return StyleConfig.Panel
    }
  },
  watch: {
    consoleState(val) {
      // console.log('consoleState 变化:', val)
      this.onPanelStateWillChange({
        name: 'Console',
        state: val,
        toggleState: () => {}
      })
    }
  },
  created() {
    // 复制布局参数值
    for (const layoutName in LayoutConfigDialog) {
      Object.assign(
        this.layout[layoutName].style,
        LayoutConfigDialog[layoutName].style
      )
    }
    // 调整布局
    for (const layoutName in LayoutConfigDialog) {
      const { nActives, maxNActives } = LayoutConfigDialog[layoutName]
      if (
        (layoutName === 'left' ||
          layoutName === 'right' ||
          layoutName === 'bottom') &&
        maxNActives > 0 &&
        nActives < 1
      ) {
        // 如果活动面板数nActives<1,表示该layout无需显示!!!
        this.selfAdaptiveLayout(layoutName, false)
      }
    }
    // 复制面板参数
    this.panels = { ...PanelConfig }
    // 重新调整面板的激活状态(state)
    for (const name in this.panels) {
      const { state } = PanelConfig[name]
      const layoutName = this.panels[name].layout
      const { nActives, maxNActives } = LayoutConfigDialog[layoutName]
      if (
        nActives <= maxNActives &&
        state &&
        this.layout[layoutName].nActives < nActives
      ) {
        this.layout[layoutName].nActives += 1
        this.panels[name].state = true
      } else {
        this.panels[name].state = false
      }
    }
    // console.log('调整后的面板:', this.panels)
  },
  methods: {
    // 更新面板参数,刷新面板区域内容
    updatePanels() {
      // 直接修改对象引用即可触发object和array的更新
      // 修改object和array内部值不一定会触发更新!!!
      this.panels = { ...this.panels }
    },
    getPanels(layoutName) {
      // 打开的面板数
      const n = this.layout[layoutName].nActives
      const arr = []
      let i = 0
      for (const name in this.panels) {
        const { title, layout } = this.panels[name]
        if (layout === layoutName) {
          let state = this.panels[name].state
          if (state && i < n) {
            i = i + 1
          } else {
            // 如果超过了active,则强制面板不可见
            state = false
          }
          arr.push({ name, title, state })
        }
      }
      return arr
    },
    getActivePanels(layoutName) {
      const arr = []
      this.getPanels(layoutName).forEach(item => {
        const { name, state } = item
        if (state) {
          arr.push(name)
        }
      })
      return arr
    },
    // 自适应flex布局调整
    selfAdaptiveLayout(layoutName, state) {
      if (layoutName === 'left') {
        if (state) {
          this.layout.left.style.width =
            LayoutConfigDialog[layoutName].style.width + 'px'
        } else {
          this.layout.left.style.width = 0
        }
        // that.resizable.width = this.layout.left.style.width
        // that.resizable.height = that.$refs.leftLayout.clientHeight
      } else if (layoutName === 'right') {
        if (state) {
          this.layout.right.style.width =
            LayoutConfigDialog[layoutName].style.width + 'px'
        } else {
          this.layout.right.style.width = 0
        }
      } else if (layoutName === 'bottom') {
        if (state) {
          this.layout.bottom.style.height =
            LayoutConfigDialog[layoutName].style.height + 'px'
        } else {
          this.layout.bottom.style.height = 0
        }
      }
      // console.log(
      //   '[selfAdaptiveLayout]:',
      //   this.layout[layoutName].style,
      //   LayoutConfigDialog[layoutName]
      // )
      if (state) {
        this.fixResizeDom(layoutName)
      }
    },
    fixResizeDom(layoutName) {
      const that = this
      this.$nextTick(() => {
        // 当resize显示的时候要修正它的宽和高
        that.onResizeShow(layoutName)
      })
    },
    onPanelStateInit(panel) {
      const { name, state } = panel
      const layoutName = this.panels[name].layout
      if (state) {
        // 记录上一次激活的面板
        this.layout[layoutName].last = name
        // console.log('记录上一次激活的面板:', layoutName, name)
      }
    },
    // 用户点击活动面板触发事件
    // 子组件PanelItem发送onPanelStateChange消息)
    onPanelStateWillChange(panel) {
      // console.log(panel)
      const { name, state, toggleState } = panel
      if (this.panels.hasOwnProperty(name)) {
        const layoutName = this.panels[name].layout
        let { nActives } = this.layout[layoutName]
        const { last } = this.layout[layoutName]
        const maxNActives = LayoutConfigDialog[layoutName].maxNActives
        // console.log(
        //   '面板:',
        //   name,
        //   '状态:',
        //   state,
        //   'layout:',
        //   layoutName,
        //   '已激活:',
        //   nActives,
        //   '最大可激活:',
        //   maxNActives
        // )
        // 是否需要重新布局
        let needReLayout = false
        if (state && nActives + 1 > maxNActives) {
          // 超过最大可打开面板个数,不可激活面板
          if (last !== '') {
            // 上一个点击的面板强制取消激活
            this.panels[last].state = false
            // 强制刷新面板组
            this.panelGroupKey = makeUUID()
          }
          // console.log(
          //   '上一个面板:',
          //   last,
          //   this.panels,
          //   '超过最大可打开面板个数,不可激活面板!!!'
          // )
        } else {
          if (state) {
            // 激活面板个数加一
            nActives += 1
          } else {
            // 激活面板个数减一
            nActives -= 1
          }
          if (state) {
            // 0 -> 1
            needReLayout = nActives === 1
          } else {
            // 1 -> 0
            needReLayout = nActives === 0
          }
        }
        // 切换面板条状态(panel-group/item.vue组件传递的函数, 激活/不激活)
        toggleState()
        // 需要重新布局
        if (needReLayout) {
          // console.log('布局:', layoutName, '需要重新调整')
          // 自适应布局调整
          this.selfAdaptiveLayout(layoutName, state)
        }
        // 更新激活面板个数
        this.layout[layoutName].nActives = nActives
        // 记录上一次激活的面板
        this.layout[layoutName].last = name
        // 更新面板状态
        this.panels[name].state = state
        // 更新"左/右区域"的内容
        this.updatePanels()
        // console.log(this.layout)
      }
    },
    onResizeShow(layoutName) {
      const parentClassName = this.layout[layoutName].className
      if (parentClassName) {
        // console.log(parentClassName)
        // 获取父节点
        const parent = this.$el.querySelector(`.${parentClassName}`)
        // console.log('client:', parent.clientHeight, 'offset:', parent.offsetHeight)
        // console.log('rect:', parent.getBoundingClientRect())
        // 修正宽度和高度
        if (layoutName === 'left' || layoutName === 'right') {
          this.resizeParams[layoutName].width = parent.clientWidth

          // 问题: 使用下面一行的代码修改height参数无效
          // 原因: resize组件内部不接收非number数据
          // this.resizeParams[layoutName].height = '100%'
          // 解决方法: 直接修改style
          const el = parent.querySelector('.resizable-component')
          if (el) {
            el.style.height = '100%'
          }
        } else if (layoutName === 'bottom') {
          // this.resizeParams[layoutName].width = '100%'
          const el = parent.querySelector('.resizable-component')
          if (el) {
            el.style.width = '100%'
          }
          this.resizeParams[layoutName].height = parent.clientHeight
        }
      }
    },
    onResizeMove(layoutName, e) {
      // console.log('拖拽面板:', e)
      if (layoutName === 'left') {
        this.layout.left.style.width = e.width + 'px'
        LayoutConfigDialog[layoutName].style.width = e.width
      } else if (layoutName === 'right') {
        this.layout.right.style.width = e.width + 'px'
        LayoutConfigDialog[layoutName].style.width = e.width
      } else if (layoutName === 'bottom') {
        this.layout.bottom.style.height = e.height + 'px'
        LayoutConfigDialog[layoutName].style.height = e.height
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@import '../style/variable.scss';
.main {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  // justify-items: stretch;
  background-color: $menu-bg-color3;
  // width: 100%;
  height: 100%;
  .left-panel-group-container {
    width: 30px;
    height: 100%;
    // flex-shrink: 0;
    flex-grow: 0;
    @extend %toolbar-color;
  }
  .layouts-container {
    height: 100%;
    flex: 1;
    text-align: center;
    .layouts {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: row;
      // align-items: stretch;
    }
    .top-layout {
      background-color: purple;
      font-size: 12px;
      display: flex;
      flex-direction: column;
      // position: relative;
    }
    .bottom-layout {
      font-size: 12px;
      background-color: yellow;
      position: relative;
      width: 100%;
    }
    .main-layout-container {
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: stretch;
      justify-items: stretch;
      width: 100%;
      height: 100%;
    }
    .left-layout {
      font-size: 12px;
      background-color: $menu-bg-color3;
      position: relative;

      // 右边框额外画一条垂线
      // &::after {
      //   content: '';
      //   // width: 1px;
      //   height: 100%;
      //   border: 1px solid blue;
      //   position: absolute;
      //   top: 0px;
      //   right: 0px;
      // }
    }
    .main-layout {
      font-size: 12px;
      background-color: green;
      // position: relative;
    }
    .right-layout {
      font-size: 12px;
      background-color: #c8b6ee;
      position: relative;
    }
  }
  .right-panel-group-container {
    height: 100%;
    // flex-shrink: 0;
    flex-grow: 0;
    width: 30px;
    @extend %toolbar-color;
  }
}
</style>
